package com.i360day.redis.publisher;

import com.i360day.redis.listener.channel.RedisMessageListenerChannel;
import com.i360day.redis.constant.RedisContextHolder;
import com.i360day.redis.exception.RedisCallbackException;
import com.i360day.redis.listener.vo.RedisResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.util.ObjectUtils;

import java.util.concurrent.TimeUnit;

/**
 * @Description 发布服务
 * @Author DengHuaQiao
 * @Date 2019/9/4 16:27
 * @Version 1.0
 */
public class RedisPubSubService {

    private Logger log = LoggerFactory.getLogger(RedisPubSubService.class);

    /**
     * 异步发送
     * 根据channel发送消息
     *
     * @param message 消息对象
     * @return
     */
    @Async
    public <T> boolean publishAsync(RedisMessageListenerChannel<T> message) {
        return publish(message);
    }

    /**
     * 使用静态方式调用，不直接注入麻烦
     * 根据channel发送消息
     *
     * @param message 消息对象
     * @return
     */
    public static <T> boolean publish(RedisMessageListenerChannel<T> message) {
        //发送队列消息
        if (message.isQueue()) {
            String queueChennel = RedisContextHolder.getQueueLeftKey(message.getClass().getName(), message.getQueueId());
            RedisContextHolder.leftPush(queueChennel, message);
            //如果队列中的值60分钟都没有被消费，则删除
            RedisContextHolder.setExpire(queueChennel, 60 * 60);
        }
        RedisContextHolder.getRedisTempate().convertAndSend(message.getClass().getName(), message);
        //是否获取同步消息
        if (message.isSynch()) {
            RedisResult redisResult = RedisContextHolder.getRightPop(RedisContextHolder.getQueueRightKey(message.getClass().getName(), message.getQueueId()), 5, TimeUnit.MINUTES).toJavaObject(RedisResult.class);
            if (!ObjectUtils.isEmpty(redisResult.getSuccess()) && redisResult.getSuccess().equals(true)) return true;
            else if (ObjectUtils.isEmpty(redisResult.getSuccess())) return false;
            else if (ObjectUtils.isEmpty(redisResult.getErrorMsg())) return false;
            throw new RedisCallbackException(ObjectUtils.isEmpty(redisResult.getErrorMsg()) ? "获取回调消息失败" : redisResult.getErrorMsg());
        }
        return true;
    }
}
